package com.lry.rpc.starter.bean;

import com.lry.proxy.Proxy;
import com.lry.proxy.ProxyFactory;
import com.lry.proxy.ProxyType;
import com.lry.router.Router;
import com.lry.router.RouterFactory;
import com.lry.router.RouterType;
import com.lry.rpc.starter.annotation.RpcReference;
import com.lry.util.StringUtils;
import lombok.Data;
import org.springframework.core.annotation.AnnotationAttributes;

@Data
public class ReferenceConfig<T> {
    protected String version;
    private String serviceImplName;//服务实现者的全路径名字
    protected String group;
    protected String merger;
    protected String token;
    protected String url;
    protected String router;
    protected String proxy;
    protected int retries;
    protected long timeout;
    protected String[] filter;
    protected String serializer;
    protected String compressor;
    protected String[] excludeMethod;
    protected String[] includeMethod;
    protected boolean async;
    private transient volatile boolean initialized;
    private transient volatile T ref;
    private transient volatile boolean destroyed;

    private Class<?> interfaceClass;



    public ReferenceConfig(Class<?> interfaceClass, AnnotationAttributes attributes,String proxy,String router) {
        this.interfaceClass  = interfaceClass;
        this.async = attributes.getBoolean("async");
        this.version = attributes.getString("version");
        this.serviceImplName = attributes.getString("serviceImplName");
        this.group = attributes.getString("group");
        this.merger = attributes.getString("merger");
        this.token = attributes.getString("token");
        this.url = attributes.getString("token");
        this.router = attributes.getString("router");

        //如果注解没有设置proxy
        if(StringUtils.isBlank(this.router)){
            //则获取全局proxy
            this.router = router;
            if(StringUtils.isBlank(this.router)){
                this.router = RouterType.ROUND_ROBIN;
            }
        }

        this.proxy = attributes.getString("proxy");
        //如果注解没有设置proxy
        if(StringUtils.isBlank(this.proxy)){
            //则获取全局proxy
            this.proxy = proxy;
            if(StringUtils.isBlank(this.proxy)){
                this.proxy = ProxyType.CGLIB;
            }
        }
        this.retries = attributes.getNumber("retries");
        this.timeout = attributes.getNumber("timeout");
        this.filter = attributes.getStringArray("filter");
        this.serializer = attributes.getString("serializer");
        this.compressor = attributes.getString("compressor");
        this.excludeMethod = attributes.getStringArray("excludeMethod");
        this.includeMethod = attributes.getStringArray("includeMethod");
    }

    public T get(){
        if (destroyed) {
            throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!");
        }
        if (ref == null) {
            init();
        }
        return ref;
    }

    private synchronized void init() {
        if(initialized){
            return;
        }
        ref = createProxy();

        initialized = true;
    }

    private T createProxy(){
        Router router = RouterFactory.getRouter(this.router);
        return ProxyFactory.getProxy(proxy,router,includeMethod,excludeMethod,group,version).getProxy(interfaceClass,serviceImplName);
    }


    public Class<?> getInterfaceClass() {
        return interfaceClass;
    }

    public void setToken(String token){
        if(StringUtils.isBlank(this.token)){
            this.token = token;
        }
    }

    public void setCompressor(String compressor) {
        if(StringUtils.isBlank(this.compressor)){
            this.compressor = compressor;
        }
    }

    public void setSerializer(String serializer) {
        if(StringUtils.isBlank(this.serializer)){
            this.serializer = serializer;
        }
    }
}
